home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd1.bin / sharewar / FFE / GRAPH.SWG / 0030_Silicon Graphics Image (SGI).pas < prev    next >
Pascal/Delphi Source File  |  1997-05-11  |  16KB  |  410 lines

  1.  
  2.                             Draft version  0.9
  3.  
  4.                         The SGI Image File Format
  5.  
  6.                              Paul Haeberli
  7.  
  8.                               paul@sgi.com
  9.  
  10.                     Silicon Graphics Computer Systems
  11.  
  12.  
  13.  
  14. This is the definitive document describing the SGI image file format.  This 
  15. is a low level spec that describes the actual byte level format of SGI image
  16. files.  On SGI machines the preferred way of reading and writing SGI image
  17. files is to use the image library -limage.  This library provides a set
  18. of functions that make it easy to read and write SGI images.  If you are 
  19. on an SGI workstation you can get info on -limage by doing:
  20.  
  21.     % man 4 rgb
  22.  
  23. A note on byte order of values in the SGI image files
  24.  
  25.     In the following description a notation like bits[7..0] is used to denote
  26.     a range of bits in a binary value.   Bit 0 is the lowest order bit in a
  27.     the value.
  28.  
  29.     All short values are represented by 2 bytes.  The first byte stores the
  30.     high order 8 bits of the value: bits[15..8].  The second byte stores
  31.     the low order 8 bits of the value: bits[7..0].  
  32.  
  33.         So, this function will read a short value from the file:
  34.  
  35.             unsigned short getshort(inf)
  36.             FILE *inf;
  37.             {
  38.                 unsigned char buf[2];
  39.  
  40.                 fread(buf,2,1,inf);
  41.                 return (buf[0]<<8)+(buf[1]<<0);
  42.             }
  43.  
  44.     All long values are represented by 4 bytes.  The first byte stores the
  45.     high order 8 bits of the value: bits[31..24].  The second byte stores
  46.     bits[23..16].  The third byte stores bits[15..8]. The forth byte stores
  47.     the low order 8 bits of the value: bits[7..0].  
  48.  
  49.         So, this function will read a long value from the file:
  50.  
  51.             static long getlong(inf)
  52.             FILE *inf;
  53.             {
  54.                 unsigned char buf[4];
  55.  
  56.                 fread(buf,4,1,inf);
  57.                 return (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0);
  58.             }
  59.  
  60.  
  61. The general structure of an SGI image file is as shown below:
  62.  
  63.     The header indicates whether the image is run length encoded (RLE).
  64.  
  65.     If the image is not run length encoded, this is the structure:
  66.  
  67.         The Header
  68.         The Image Data
  69.  
  70.     If the image is run length encoded, this is the structure:
  71.  
  72.         The Header
  73.         The Offset Tables 
  74.         The Image Data
  75.  
  76.  
  77. The Header
  78.  
  79.     The header consists of the following:
  80.  
  81.        Size  | Type   | Name      | Description   
  82.  
  83.      2 bytes | short  | MAGIC     | IRIS image file magic number
  84.      1 byte  | char   | STORAGE   | Storage format
  85.      1 byte  | char   | BPC       | Number of bytes per pixel channel 
  86.      2 bytes | ushort | DIMENSION | Number of dimensions
  87.      2 bytes | ushort | XSIZE     | X size in pixels 
  88.      2 bytes | ushort | YSIZE     | Y size in pixels 
  89.      2 bytes | ushort | ZSIZE     | Number of channels
  90.      4 bytes | long   | PIXMIN    | Minimum pixel value
  91.      4 bytes | long   | PIXMAX    | Maximum pixel value
  92.      4 bytes | char   | DUMMY     | Ignored
  93.     80 bytes | char   | IMAGENAME | Image name
  94.      4 bytes | long   | COLORMAP  | Colormap ID
  95.    404 bytes | char   | DUMMY     | Ignored
  96.  
  97.  
  98.     Here is a description of each field in the image file header:
  99.  
  100.         MAGIC - This is the decimal value 474 saved as a short. This
  101.         identifies the file as an SGI image file.
  102.  
  103.         STORAGE - specifies whether the image is stored using run
  104.         length encoding (RLE) or not (VERBATIM).   If RLE is used, the value 
  105.         of this byte will be 1.  Otherwise the value of this byte will be 0.
  106.         The only allowed values for this field are  0 and 1.
  107.  
  108.         BPC - describes the precision that is used to store each
  109.         channel of an image.  This is the number of bytes per pixel
  110.         component.  The majority of SGI image files use 1 byte per 
  111.         pixel component, giving 256 levels.  Some SGI image files use 
  112.         2 bytes per component.  The only allowed values for this field 
  113.         are  1 and 2.
  114.  
  115.         DIMENSION - described the number of dimensions in the data stored
  116.         in the image file.  The only allowed values are 1, 2, or 3.  If
  117.         this value is 1, the image file consists of only 1 channel and 
  118.         only 1 scanline.  The length of this scan line is given by the 
  119.         value of XSIZE below.  If this value is 2, the file consists of a 
  120.         single channel with a number of scan lines. The width and height
  121.         of the image are given by the values of XSIZE and YSIZE below.
  122.         If this value is 3, the file consists of a number of channels.
  123.         The width and height of the image are given by the values of 
  124.         XSIZE and YSIZE below.  The number of channels is given by the 
  125.         value of ZSIZE below.  
  126.  
  127.         XSIZE - The width of the image in pixels
  128.  
  129.         YSIZE - The height of the image in pixels
  130.  
  131.         ZSIZE - The number of channels in the image.  B/W images are stored 
  132.         as 2 dimensional images with a ZSIZE or 1.  RGB color images are 
  133.         stored as 3 dimensional images with a ZSIZE of 3.  An RGB image with 
  134.         an ALPHA channel is stored as a 3 dimensional image with a ZSIZE of 
  135.         4.  There are no inherent limitations in the SGI image file format 
  136.         that would preclude the creation of image files with more than 4
  137.         channels.
  138.  
  139.         PINMIN - The minimum pixel value in the image.  The value of
  140.         0 may be used if no pixel has a value that is smaller than 0.
  141.  
  142.         PINMAX - The maximum pixel value in the image.  The value of
  143.         255 may be used if no pixel has a value that is greater than 255.
  144.         This is the value that is considered to be full brightness in 
  145.         the image.  
  146.  
  147.         DUMMY - This 4 bytes of data should be set to 0. 
  148.  
  149.         IMAGENAME - An null terminated ascii string of up to 79 characters 
  150.         terminated by a null may be included here.  This is not commonly
  151.         used.
  152.  
  153.         COLORMAP - This controls how the pixel values in the file should be
  154.         interpreted.  It can have one of these four values:
  155.  
  156.             0:  NORMAL - The data in the channels represent B/W values
  157.                 for images with 1 channel, RGB values for images with 3
  158.                 channels, and RGBA values for images with 4 channels.
  159.                 Almost all the SGI image files are of this type. 
  160.  
  161.             1:  DITHERED - The image will have only 1 channel of data.
  162.                 For each pixel, RGB data is packed into one 8 bit value.
  163.                 3 bits are used for red and green, while blue uses 2 bits.
  164.                 Red data is found in bits[2..0], green data in bits[5..3],
  165.                 and blue data in bits[7..6].  This format is obsolete.
  166.  
  167.             2:  SCREEN - The image will have only 1 channel of data.
  168.                 This format was used to store color-indexed pixels.
  169.                 To convert the pixel values into RGB values a colormap
  170.                 must be used.  The appropriate color map varies from
  171.                 image to image.  This format is obsolete.
  172.  
  173.             3:  COLORMAP - The image is used to store a color map from
  174.                 an SGI machine.  In this case the image is not displayable
  175.                 in the conventional sense.
  176.  
  177.         DUMMY - This 404 bytes of data should be set to 0. This makes the
  178.         header exactly 512 bytes. 
  179.  
  180.  
  181. The Image Data (if not RLE)
  182.  
  183.     If the image is stored verbatim (without RLE), the image data directly
  184.     follows the 512 byte header.  The data for each scanline in the first
  185.     channel is written first.  If the image has more than 1 channel the 
  186.     remaining channels follow the first channel in numerical order.  If the
  187.     BPC value is 1, then each scan line is written as XSIZE bytes.  If the BPC 
  188.     value is 2, then each scanline is written as XSIZE shorts.  These shorts 
  189.     are stored in the byte order described above.
  190.  
  191.  
  192. The Offset Tables (if RLE)
  193.  
  194.     If the image is stored using run length encoding, offset tables
  195.     follow the header that describe what the file offsets are to the 
  196.     RLE for each scanline.  This information only applies if the value 
  197.     for STORAGE above is 1.
  198.  
  199.             Size  | Type   | Name      | Description   
  200.  
  201.      tablen longs | long   | STARTTAB  | Start table
  202.      tablen longs | long   | LENGTHTAB | Length table
  203.  
  204.     One entry in each table is needed for each scan line of RLE data.  The 
  205.     total number of scanlines in the image (tablen) is determined by the
  206.     product of the YSIZE and ZSIZE.  There are two tables of longs that 
  207.     are written. Each consists of tablen longs of data.  The first
  208.     table has the file offsets to the RLE data for each scan line in the
  209.     image.  In a file with more than 1 channel (ZSIZE > 1) this table first 
  210.     has all the offsets for the scanlines in the first channel, followed
  211.     be offsets for the scanlines in the second channel, etc.  The second 
  212.     table has the RLE data length for each scan line in the image.  In a 
  213.     file with more than 1 channel (ZSIZE > 1) this table first has all the 
  214.     RLE data lengths for the scanlines in the first channel, followed
  215.     be RLE data lengths for the scanlines in the second channel, etc.
  216.  
  217.     To find the the file offset, and the number of bytes in the RLE data 
  218.     for a particular scanline, these two arrays may be read in and indexed as
  219.     follows: 
  220.  
  221.         To read in the tables:
  222.  
  223.             unsigned long *starttab, *lengthtab;
  224.  
  225.             tablen = ysize*zsize*sizeof(long);
  226.             starttab = (unsigned long *)mymalloc(tablen);
  227.             lengthtab = (unsigned long *)mymalloc(tablen);
  228.             fseek(inf,512,SEEK_SET);
  229.             readlongtab(inf,starttab);
  230.             readlongtab(ing,lengthtab);
  231.  
  232.  
  233.         To find the file offset and RLE data length for a scanline:
  234.  
  235.             rowno is an integer in the range 0 to YSIZE-1
  236.             channo is an integer in the range 0 to ZSIZE-1
  237.  
  238.             rleoffset = starttab[rowno+channo*YSIZE]
  239.             rlelength = lengthtab[rowno+channo*YSIZE]
  240.     
  241.  
  242. The Image Data (if RLE)
  243.  
  244.     This information only applies if the value for STORAGE above is 1.  If
  245.     the image is stored using run length encoding, the image data follows
  246.     the offset tables above.  The RLE data is not in any particular order.
  247.     The offset tables above are used to locate the rle data for any scanline.
  248.   
  249.     The RLE data must be read in from the file and expanded into pixel 
  250.     data in the following manner:
  251.  
  252.     If BPC is 1, then there is one byte per pixel.  In this case the 
  253.     RLE data should be read into an array of chars.  To expand
  254.     data, the low order seven bits of the first byte: bits[6..0]
  255.     are used to form a count.  If the high order bit of the first
  256.     byte is 1: bit[7], then the count is used to specify how many
  257.     bytes to copy from the RLE data buffer to the destination.
  258.     Otherwise, if the high order bit of the first byte is 0: bit[7],
  259.     then the count is used to specify how many times to repeat the 
  260.     value of the following byte, in the destination.  This process
  261.     continues until a count of 0 is found.  This should decompress
  262.     exactly XSIZE pixels.  
  263.  
  264.         Here is example code to decompress a scanline:
  265.  
  266.             expandrow(optr,iptr,z)
  267.             unsigned char *optr, *iptr;
  268.             int z;
  269.             {
  270.                 unsigned char pixel, count;
  271.             
  272.                 optr += z;
  273.                 while(1) {
  274.                     pixel = *iptr++;
  275.                     if ( !(count = (pixel & 0x7f)) )
  276.                         return;
  277.                     if(pixel & 0x80) {
  278.                         while(count--) {
  279.                             *optr = *iptr++;
  280.                             optr+=4;
  281.                         }
  282.                     } else {
  283.                         pixel = *iptr++;
  284.                         while(count--) {
  285.                             *optr = pixel;
  286.                             optr+=4;
  287.                         }
  288.                     }
  289.                 }
  290.             }
  291.  
  292.     If BPC is 2, there is one short (2 bytes) per pixel.  In this 
  293.     case the RLE data should be read into an array of shorts.  To 
  294.     expand data, the low order seven bits of the first short: bits[6..0]
  295.     are used to form a count.  If bit[7] of the first short is 1, then 
  296.     the count is used to specify how many shorts to copy from the RLE 
  297.     data buffer to the destination.  Otherwise, if bit[7] of the first 
  298.     short is 0, then the count is used to specify how many times to 
  299.     repeat the value of the following short, in the destination.  This 
  300.     process proceeds until a count of 0 is found.  This should decompress
  301.     exactly XSIZE pixels.  Note that the byte order of short data in
  302.     on the input file should be observed, as described above.
  303.  
  304.  
  305. Implementation notes
  306.  
  307.     Implementation of both RLE and VERBATIM format for images with
  308.     BPC of 1 is required since the great majority of SGI images are in
  309.     this format.  Support for images with a 2 BPC is encouraged.
  310.  
  311.     If the ZSIZE of an image is 1, it is assumed to represent B/W
  312.     values.  If the ZSIZE is 3, it is assumed to represent RGB data,
  313.     and if ZSIZE is 4, it is assumed to contain RGB data with alpha.
  314.  
  315.  
  316. Naming Conventions
  317.  
  318.     On SGI systems, SGI image files end with the extension .bw if
  319.     they are B/W images, they end in .rgb if they contain RGB image
  320.     data, and end in .rgba if they are RGB images with alpha channel.
  321.  
  322.     Sometimes the .sgi extension is used as well.
  323.  
  324. An example
  325.  
  326.     This program will write out a valid B/W SGI image file:
  327.  
  328.     #include "stdio.h"
  329.  
  330.     #define IXSIZE      (23)
  331.     #define IYSIZE      (15)
  332.  
  333.     putbyte(outf,val)
  334.     FILE *outf;
  335.     unsigned char val;
  336.     {
  337.         unsigned char buf[1];
  338.  
  339.         buf[0] = val;
  340.         fwrite(buf,1,1,outf);
  341.     }
  342.  
  343.     putshort(outf,val)
  344.     FILE *outf;
  345.     unsigned short val;
  346.     {
  347.         unsigned char buf[2];
  348.  
  349.         buf[0] = (val>>8);
  350.         buf[1] = (val>>0);
  351.         fwrite(buf,2,1,outf);
  352.     }
  353.  
  354.     static int putlong(outf,val)
  355.     FILE *outf;
  356.     unsigned long val;
  357.     {
  358.         unsigned char buf[4];
  359.  
  360.         buf[0] = (val>>24);
  361.         buf[1] = (val>>16);
  362.         buf[2] = (val>>8);
  363.         buf[3] = (val>>0);
  364.         return fwrite(buf,4,1,outf);
  365.     }
  366.  
  367.     main()
  368.     {
  369.         FILE *of;
  370.         char iname[80];
  371.         unsigned char outbuf[IXSIZE];
  372.         int i, x, y;
  373.  
  374.         of = fopen("example.rgb","w");
  375.         if(!of) {
  376.             fprintf(stderr,"sgiimage: can't open output file\n");
  377.             exit(1);
  378.         }
  379.         putshort(of,474);       /* MAGIC                */
  380.         putbyte(of,0);          /* STORAGE is VERBATIM  */
  381.         putbyte(of,1);          /* BPC is 1             */
  382.         putshort(of,2);         /* DIMENSION is 2       */
  383.         putshort(of,IXSIZE);    /* XSIZE                */
  384.         putshort(of,IYSIZE);    /* YSIZE                */
  385.         putshort(of,1);         /* ZSIZE                */
  386.         putlong(of,0);          /* PIXMIN is 0          */
  387.         putlong(of,255);        /* PIXMAX is 255        */
  388.         for(i=0; i<4; i++)      /* DUMMY 4 bytes        */
  389.             putbyte(of,0);
  390.         strcpy(iname,"No Name");
  391.         fwrite(iname,80,1,of);  /* IMAGENAME            */
  392.         putlong(of,0);          /* COLORMAP is 0        */
  393.         for(i=0; i<404; i++)    /* DUMMY 404 bytes      */
  394.             putbyte(of,0);
  395.  
  396.         for(y=0; y<IYSIZE; y++) {
  397.             for(x=0; x<IXSIZE; x++) 
  398.                 outbuf[x] = (255*x)/(IXSIZE-1);
  399.             fwrite(outbuf,IXSIZE,1,of);
  400.         }
  401.         fclose(of);
  402.     }
  403.  
  404.  
  405. -- 
  406.  
  407. paul haeberli
  408. paul@sgi.com
  409.  
  410.